Index: src/org/apache/axis/deployment/wsdd/WSDDDeployment.java
===================================================================
--- src/org/apache/axis/deployment/wsdd/WSDDDeployment.java	(revision 382661)
+++ src/org/apache/axis/deployment/wsdd/WSDDDeployment.java	(working copy)
@@ -165,6 +165,19 @@
             deployMapping(typeMapping);
     }
 
+    public void undeployTypeMapping(WSDDTypeMapping typeMapping)
+    {
+        QName qname = typeMapping.getQName();
+        String encoding = typeMapping.getEncodingStyle();
+
+        // We have to include the encoding in the key
+        // because otherwise we would overwrite exiting mappings
+        typeMappings.remove(qname + encoding);
+
+        if (tmrDeployed)
+            undeployMapping(typeMapping);
+    }
+
     /**
      * Default constructor
      */
@@ -328,6 +341,11 @@
         }
     }
 
+    private void undeployMapping(WSDDTypeMapping mapping)
+    {
+        // not implemented
+    }
+
     public void writeToContext(SerializationContext context)
         throws IOException
     {
Index: src/org/apache/axis/deployment/wsdd/WSDDUndeployment.java
===================================================================
--- src/org/apache/axis/deployment/wsdd/WSDDUndeployment.java	(revision 382661)
+++ src/org/apache/axis/deployment/wsdd/WSDDUndeployment.java	(working copy)
@@ -64,6 +64,11 @@
         services.add(service);
     }
     
+    public void addTypeMapping(WSDDTypeMapping typeMapping) 
+    {
+        typeMappings.add(typeMapping);
+    }
+
     public void deployTypeMapping(WSDDTypeMapping typeMapping)
         throws WSDDException
     {
@@ -118,9 +123,6 @@
             addService(getQName(elements[i]));
         }
 
-        /*
-        // How to deal with undeploying mappings?
-
         elements = getChildElements(e, ELEM_WSDD_TYPEMAPPING);
         for (i = 0; i < elements.length; i++) {
             WSDDTypeMapping mapping = new WSDDTypeMapping(elements[i]);
@@ -132,7 +134,6 @@
             WSDDBeanMapping mapping = new WSDDBeanMapping(elements[i]);
             addTypeMapping(mapping);
         }
-        */
     }
 
     protected QName getElementName()
@@ -175,6 +176,11 @@
             }
             registry.undeployService(qname);
         }
+
+        for (int n = 0; n < typeMappings.size(); n++) {
+            WSDDTypeMapping mapping  = (WSDDTypeMapping)typeMappings.get(n);
+            registry.undeployTypeMapping(mapping);
+        }
     }
 
     private void writeElement(SerializationContext context,
Index: src/org/apache/axis/encoding/ser/BeanSerializer.java
===================================================================
--- src/org/apache/axis/encoding/ser/BeanSerializer.java	(revision 382661)
+++ src/org/apache/axis/encoding/ser/BeanSerializer.java	(working copy)
@@ -175,9 +175,11 @@
                         if (propValue == null) {
                             // an element cannot be null if nillable property is set to 
                             // "false" and the element cannot be omitted
+                            /*
                             if (!isNillable && !isOmittable) {
                                 throw new IOException(Messages.getMessage("nullNonNillableElement", propName));
                             }
+                            */
                             
                             // if meta data says minOccurs=0, then we can skip
                             // it if its value is null and we aren't doing SOAP
Index: src/org/apache/axis/MessageContext.java
===================================================================
--- src/org/apache/axis/MessageContext.java	(revision 382661)
+++ src/org/apache/axis/MessageContext.java	(working copy)
@@ -379,9 +379,11 @@
      * during finalization, the dispose() method is called.
      * @see #dispose()
      */
+    /*
     protected void finalize() {
         dispose();
     }
+    */
 
     /**
      * Mappings of QNames to serializers/deserializers (and therfore
Index: src/org/apache/axis/wsdl/toJava/JavaBeanWriter.java
===================================================================
--- src/org/apache/axis/wsdl/toJava/JavaBeanWriter.java	(revision 382661)
+++ src/org/apache/axis/wsdl/toJava/JavaBeanWriter.java	(working copy)
@@ -651,7 +651,12 @@
             if (elements != null) {
                 for (int j = 0; j < elements.size(); j++) {
                     ElementDecl elem = (ElementDecl) elements.get(j);
-                    paramTypes.add(elem.getType().getName());
+                    String typeName = elem.getType().getName();
+                    if (elem.getMinOccursIs0() || elem.getNillable() ||
+                        elem.getOptional()) {
+                        typeName = Utils.getWrapperType(typeName);
+                    }
+                    paramTypes.add(typeName);
                     paramNames.add(JavaUtils.getUniqueValue(
                             helper.reservedPropNames, elem.getName()));
                 }
Index: src/org/apache/axis/wsdl/symbolTable/Utils.java
===================================================================
--- src/org/apache/axis/wsdl/symbolTable/Utils.java	(revision 382661)
+++ src/org/apache/axis/wsdl/symbolTable/Utils.java	(working copy)
@@ -23,6 +23,7 @@
 import javax.xml.namespace.QName;
 import javax.xml.rpc.holders.BooleanHolder;
 import java.util.HashMap;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
@@ -38,7 +39,7 @@
 public class Utils {
 
     /** cache of namespaces -> maps of localNames -> QNames */
-    static final Map nsmap = new HashMap();
+    static final Map nsmap = Collections.synchronizedMap(new HashMap());
 
     /**
      * Find or create a QName with the specified namespace/localName.
@@ -55,7 +56,7 @@
         Map ln2qn = (Map) nsmap.get(namespace);
 
         if (null == ln2qn) {        // cache miss
-            ln2qn = new HashMap();
+            ln2qn = Collections.synchronizedMap(new HashMap());
 
             nsmap.put(namespace, ln2qn);
 
Index: src/org/apache/axis/description/TypeDesc.java
===================================================================
--- src/org/apache/axis/description/TypeDesc.java	(revision 382661)
+++ src/org/apache/axis/description/TypeDesc.java	(working copy)
@@ -125,6 +125,14 @@
         return result;
     }
 
+    /**
+     * Clears the TypeDesc cache.
+     */
+    public static void clearCache() 
+    {
+        classMap.clear();
+    }
+
     /** The Java class for this type */
     private Class javaClass = null;
 
Index: src/org/apache/axis/transport/http/CommonsHTTPSender.java
===================================================================
--- src/org/apache/axis/transport/http/CommonsHTTPSender.java	(revision 382661)
+++ src/org/apache/axis/transport/http/CommonsHTTPSender.java	(working copy)
@@ -229,6 +229,13 @@
                 }
             }
             
+            // always release the connection back to the pool if 
+            // it was one way invocation
+            if (msgContext.isPropertyTrue("axis.one.way")) {
+                method.releaseConnection();
+                return;
+            }
+                
             // wrap the response body stream so that close() also releases 
             // the connection back to the pool.
             InputStream releaseConnectionOnCloseStream = 
@@ -271,12 +278,6 @@
                 
             }
 
-            // always release the connection back to the pool if 
-            // it was one way invocation
-            if (msgContext.isPropertyTrue("axis.one.way")) {
-                method.releaseConnection();
-            }
-            
         } catch (Exception e) {
             log.debug(e);
             throw AxisFault.makeFault(e);
@@ -688,7 +689,7 @@
         }
 
         public boolean isRepeatable() {
-            return false;
+            return true;
         }
 
         public void writeRequest(OutputStream out) throws IOException {
@@ -700,7 +701,9 @@
         }
 
         public long getContentLength() {
-            if (this.method.getParams().getVersion() == HttpVersion.HTTP_1_0) {
+            if (this.method.getParams().getVersion() == HttpVersion.HTTP_1_0 ||
+                this.method.getParams().isParameterTrue(
+                                        "transport.http.disableChunking")) {
                 try {
                     return message.getContentLength();
                 } catch (Exception e) {
Index: src/org/apache/axis/utils/JavaUtils.java
===================================================================
--- src/org/apache/axis/utils/JavaUtils.java	(revision 382661)
+++ src/org/apache/axis/utils/JavaUtils.java	(working copy)
@@ -41,7 +41,9 @@
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Date;
+import java.util.Map;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
@@ -954,7 +956,7 @@
      * Used to cache a result from IsEnumClassSub(). 
      * Class->Boolean mapping.
      */
-    private static HashMap enumMap = new HashMap();
+    private static Map enumMap = Collections.synchronizedMap(new HashMap());
     
     /**
      * Determine if the class is a JAX-RPC enum class.
@@ -972,6 +974,10 @@
         return b.booleanValue();
     }
 
+    public static void clearEnumCache() {
+        enumMap.clear();
+    }
+
     private static boolean isEnumClassSub(Class cls) {
         try {
             java.lang.reflect.Method[] methods = cls.getMethods();
Index: src/org/apache/axis/utils/cache/MethodCache.java
===================================================================
--- src/org/apache/axis/utils/cache/MethodCache.java	(revision 382661)
+++ src/org/apache/axis/utils/cache/MethodCache.java	(working copy)
@@ -63,6 +63,16 @@
     }
 
     /**
+     * Clears the method cache.
+     */
+    public void clearCache() {
+        Map map = (Map) cache.get();
+        if (map != null) {
+            map.clear();
+        }
+    }
+
+    /**
      * Returns the per thread hashmap (for method caching)
      */
     private Map getMethodCache() {
Index: src/org/apache/axis/utils/cache/JavaClass.java
===================================================================
--- src/org/apache/axis/utils/cache/JavaClass.java	(revision 382661)
+++ src/org/apache/axis/utils/cache/JavaClass.java	(working copy)
@@ -76,4 +76,12 @@
 
         return jm.getMethod();
     }
+
+    /**
+     * Clears the class cache.
+     */
+    public static synchronized void clearCache() {
+        classes.clear();
+    }
+    
 };
Index: src/org/apache/axis/AxisProperties.java
===================================================================
--- src/org/apache/axis/AxisProperties.java	(revision 382661)
+++ src/org/apache/axis/AxisProperties.java	(working copy)
@@ -84,6 +84,11 @@
     private static NameDiscoverers nameDiscoverer;
     private static ClassLoaders loaders;
 
+    public static synchronized void reset() {
+        loaders = null;
+        nameDiscoverer = null;
+    }
+
     public static void setClassOverrideProperty(Class clazz, String propertyName) {
         getAlternatePropertyNameDiscoverer()
             .addClassToPropertyNameMapping(clazz.getName(), propertyName);
Index: src/org/apache/axis/client/Call.java
===================================================================
--- src/org/apache/axis/client/Call.java	(revision 382661)
+++ src/org/apache/axis/client/Call.java	(working copy)
@@ -91,6 +91,7 @@
 import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.Vector;
+import java.util.LinkedList;
 import java.rmi.RemoteException;
 
 /**
@@ -2779,12 +2780,118 @@
                 msgContext.removeProperty(Call.ONE_WAY);
             }
         };
+
+        NotificationManager.fireNotification(runnable);
+    }
+
+    private static class NotificationManager {
+
+        private static final int DEFAULT_NOTIFICATION_EXPONENT = 2;
+
+        private static double notificationExponent = getNotificationExponent();
+        private static NotificationManager notificationManager = 
+            new NotificationManager(notificationExponent);
+
+        public static void fireNotification(Runnable runnable) {
+            if (notificationExponent <= 1) {
         //create a thread to run it
         Thread thread = new Thread(runnable);
         //run it
         thread.start();
+            } else {
+                notificationManager.enqueue(runnable);
+            }
+        }
+
+        public static double getNotificationExponent() {
+            String prop = 
+                System.getProperty("axis.notificationThreadExponent");
+            return (prop == null) ? 
+                DEFAULT_NOTIFICATION_EXPONENT : Double.parseDouble(prop);
+        }
+        
+        // end of static stuff
+
+        private Queue queue;
+        private ArrayList threads;
+        private double exponent;
+        private int computedSize;
+
+        private NotificationManager(double exponent) {
+            this.exponent = exponent;
+            this.queue = new Queue();
+            this.threads = new ArrayList();
+            this.computedSize = 0;
+        }
+        
+        public void enqueue(Runnable r) {
+            int size = this.queue.enqueue(r);
+            addThread(size);
+        }
+        
+        private synchronized void computeSize() {
+            this.computedSize = 
+                (int)Math.pow(this.threads.size(), this.exponent);
+        }
+
+        private synchronized void addThread(int size) {
+            if (size > this.computedSize) {
+                NotificationThread thread = new NotificationThread();
+                thread.setDaemon(true);
+                this.threads.add(thread);
+                thread.start();
+                computeSize();
+            }
+        }
+
+        private synchronized void removeThread(Thread thread) {
+            this.threads.remove(thread);
+            computeSize();
+        }
+        
+        private class NotificationThread extends Thread {
+
+            public void run() {
+                Runnable r = null;
+                while(true) {
+                    try {
+                        r = (Runnable)queue.dequeue();
+                    } catch (InterruptedException e) {
+                        break;
+                    }
+                    if (r == null) {
+                        break;
+                    }
+                    try {
+                        r.run();
+                    } catch (Throwable e) {
+                        log.debug(Messages.getMessage("exceptionPrinting"), e);
+                    }
+                }
+                removeThread(this);
+            }
+        }
     }
+    
+    private static class Queue {
 
+        private LinkedList queue = new LinkedList();
+        
+        public synchronized int enqueue(Runnable r) {
+            queue.add(r);
+            notify();
+            return queue.size();
+        }
+        
+        public synchronized Object dequeue() throws InterruptedException {
+            if (queue.isEmpty()) {
+                wait(1000 * 60 * 2);
+            }
+            return (queue.isEmpty()) ? null : queue.removeFirst();
+        }
+        
+    }
+
     /**
      * Get the output parameters (if any) from the last invocation.
      * 
